package edu.westga.recommender.model;

import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.AveragingPreferenceInferrer;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;

import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
import org.xml.sax.InputSource;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.FileInputStream;
import java.util.List;

public class UserNeighborSimilarity {
		
	public UserNeighborSimilarity(){
	}
	
	public String RecommendNow(long userId, int neighborhoodSize, File recsFile){
	try{
	    String docIdsTitle = "docIdsTitles.xml";
	    InputSource is = new InputSource(new FileInputStream(docIdsTitle));
	    SAXParserFactory factory = SAXParserFactory.newInstance();
	    factory.setValidating(false);
	    SAXParser sp = factory.newSAXParser();
	    ContentHandler handler = new ContentHandler();
	    sp.parse(is, handler);
	    //create the data model
	    FileDataModel dataModel = new FileDataModel(recsFile);
	    System.out.println("Data Model: Users: " + dataModel.getNumUsers() + " Items: " + dataModel.getNumItems());

	    UserSimilarity userSimilarity = new PearsonCorrelationSimilarity(dataModel);
		// Optional:
	    userSimilarity.setPreferenceInferrer(new AveragingPreferenceInferrer(dataModel));
	    //Get a neighborhood of users
	    UserNeighborhood neighborhood =
	            new NearestNUserNeighborhood(neighborhoodSize, userSimilarity, dataModel);
	    //Create the recommender
	    Recommender recommender =
	            new GenericUserBasedRecommender(dataModel, neighborhood, userSimilarity);
	    System.out.println("-----");
	    System.out.println("User: " + userId);
	    //Print out the users own preferences first
	    TasteUtils.printPreferences(dataModel, userId, handler.map);
	    if (true) {
	      long[] users = neighborhood.getUserNeighborhood(userId);
	      for (int i = 0; i < users.length; i++) {
	        long neighbor = users[i];
	        System.out.println("Neighbor: " + neighbor);
	        TasteUtils.printCommonalities(dataModel, userId, neighbor, handler.map);
	      }

	      System.out.println("");
	    }
	    //Get the top 5 recommendations
	    List<RecommendedItem> recommendations =
	            recommender.recommend(userId, 5);
	    return TasteUtils.printRecs(recommendations, handler.map);
	  }catch (Exception e){
		  return e.getMessage();
	  }
	}
}
